package com.feige.utils.jwt;

import cn.hutool.core.util.StrUtil;
import com.feige.utils.constant.Constants;
import io.jsonwebtoken.*;
import org.joda.time.DateTime;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * @author feige
 */

@Component
public class JwtUtils {

    private static Key getKeyInstance() {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] bytes = DatatypeConverter.parseBase64Binary(Constants.APP_SECRET);
        return new SecretKeySpec(bytes,signatureAlgorithm.getJcaName());
    }

    /**
     * 根据JwtInfo生成token
     * @param jwtInfo
     * @return
     */
    public String createTokenByJwtInfo(JwtInfo jwtInfo){
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject(jwtInfo.getId().toString())
                //颁发时间
                .setIssuedAt(new Date())
                //过期时间
                .setExpiration(DateTime.now().plusSeconds(Constants.TOKEN_EXPIRE).toDate())
                .claim("id", jwtInfo.getId())
                .claim("name", jwtInfo.getName())
                .claim("email", jwtInfo.getEmail())
                .claim("phoneNumber",jwtInfo.getPhoneNumber())
                .signWith(SignatureAlgorithm.HS256, getKeyInstance())
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }


    /**
     * 根据token获取jwt
     * @param jwtToken
     * @return
     */
    public JwtInfo getJwtInfoByToken(String jwtToken) {
        if (StrUtil.isNotBlank(jwtToken) && jwtToken.startsWith(Constants.TOKEN_PREFIX)) {
            jwtToken = jwtToken.substring(Constants.TOKEN_PREFIX.length());
        } else {
            // 不按规范,不允许通过验证
            return null;
        }
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
            Claims claims = claimsJws.getBody();
            return new JwtInfo(
                    Long.parseLong( claims.get("id").toString()),
                    claims.get("name").toString(),
                    claims.get("phoneNumber").toString(),
                    claims.get("email").toString()
            );
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 根据token获取id
     * @param token
     * @return
     */
    public String getUserIdByToken(String token) {
        if(StringUtils.isEmpty(token)) {
            return null;
        }
        return Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(token).getBody().getSubject();
    }

    public String refreshJwtToken(String jwtToken){
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return Jwts.builder().setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject(claims.getSubject())
                //颁发时间
                .setIssuedAt(new Date())
                //过期时间
                .setExpiration(DateTime.now().plusSeconds(Constants.TOKEN_EXPIRE).toDate())
                .setClaims(claims)
                .signWith(SignatureAlgorithm.HS256, getKeyInstance())
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }
}
